﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;

namespace DataInterpolator.Model
{
   [XmlType("LogData")]
   public class Well_LogData : IEnumerable<Well_LogData.LogDataRow>
   {
      public Well_LogData()
      {
         Time = new List<double>();
         Depth = new List<double>();
         DT1 = new List<double>();
         RhoB1 = new List<double>();
         Velocity = new List<double>();
      }

      public void Add(LogDataRow row)
      {
         Time.Add(row.Time);
         Depth.Add(row.Depth);
         DT1.Add(row.DT1);
         RhoB1.Add(row.RhoB1);
         Velocity.Add(row.Velocity);
      }

      public int Count
      {
         get
         {
            return Time.Count;
         }
      }

      [XmlIgnore()]
      public LogDataRow this[int index]
      {
         get
         {
            if (index < 0 || index >= Time.Count)
               throw new IndexOutOfRangeException();

            return new LogDataRow(this, index);
         }
      }

      [XmlArray("TimeValues")]
      [XmlArrayItem("Value")]
      public List<double> Time
      {
         get; set;
      }

      [XmlArray("DepthValues")]
      [XmlArrayItem("Value")]
      public List<double> Depth
      {
         get; set;
      }

      [XmlArray("DT1Values")]
      [XmlArrayItem("Value")]
      public List<double> DT1
      {
         get; set;
      }

      [XmlArray("RhoB1Values")]
      [XmlArrayItem("Value")]
      public List<double> RhoB1
      {
         get; set;
      }

      [XmlArray("VelocityValues")]
      [XmlArrayItem("Value")]
      public List<double> Velocity
      {
         get; set;
      }
      public IEnumerator<LogDataRow> GetEnumerator()
      {
         for (int i = 0; i < Time.Count; i++)
         {
            yield return new LogDataRow(this, i);
         }
      }

      IEnumerator IEnumerable.GetEnumerator()
      {
         return this.GetEnumerator();
      }

      public class LogDataRow
      {
         private readonly Well_LogData _LogData = null;
         private readonly int _Index = 0;
         private readonly double[] _InternalData = null;

         public LogDataRow()
         {
            _InternalData = new double[5];
         }

         public LogDataRow(Well_LogData logData, int index)
         {
            _LogData = logData;
            _Index = index;
         }

         [XmlAttribute]
         public double Time
         {
            get
            {
               if (_InternalData != null)
               {
                  return _InternalData[0];
               }
               else
               {
                  return _LogData.Time[_Index];
               }
            }
            set
            {
               if (_InternalData != null)
               {
                  _InternalData[0] = value;
               }
               else
               {
                  _LogData.Time[_Index] = value;
               }
            }
         }

         [XmlAttribute]
         public double Depth
         {
            get
            {
               if (_InternalData != null)
               {
                  return _InternalData[1];
               }
               else
               {
                  return _LogData.Depth[_Index];
               }
            }
            set
            {
               if (_InternalData != null)
               {
                  _InternalData[1] = value;
               }
               else
               {
                  _LogData.Depth[_Index] = value;
               }
            }
         }

         [XmlAttribute]
         public double DT1
         {
            get
            {
               if (_InternalData != null)
               {
                  return _InternalData[2];
               }
               else
               {
                  return _LogData.DT1[_Index];
               }
            }
            set
            {
               if (_InternalData != null)
               {
                  _InternalData[2] = value;
               }
               else
               {
                  _LogData.DT1[_Index] = value;
               }
            }
         }

         [XmlAttribute]
         public double RhoB1
         {
            get
            {
               if (_InternalData != null)
               {
                  return _InternalData[3];
               }
               else
               {
                  return _LogData.RhoB1[_Index];
               }
            }
            set
            {
               if (_InternalData != null)
               {
                  _InternalData[3] = value;
               }
               else
               {
                  _LogData.RhoB1[_Index] = value;
               }
            }
         }

         [XmlAttribute]
         public double Velocity
         {
            get
            {
               if (_InternalData != null)
               {
                  return _InternalData[4];
               }
               else
               {
                  return _LogData.Velocity[_Index];
               }
            }
            set
            {
               if (_InternalData != null)
               {
                  _InternalData[4] = value;
               }
               else
               {
                  _LogData.Velocity[_Index] = value;
               }
            }
         }
      }
   }
}
